#include "systemmonitor.h"
#include <QProcess>
#include <QDebug>
#include <QThreadPool>
#include <QDateTime>
#include <QFile>
#include "logger.h"  // 假设你有一个logger.h文件来处理日志
#include "networkmanager.h"
#include "qtconcurrentrun.h"

SystemMonitor::SystemMonitor(QObject *parent)
    : QObject(parent), m_cpuUsage(0.0), m_memoryUsage(0.0), m_temperature(0.0),
    m_threadPoolUsage("0/0"), m_currentTime(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")),
    m_diskUsage(0.0), m_networkUpload(0.0), m_networkDownload(0.0),
    m_gpuUsage(0.0), m_gpuTemperature(0.0), m_systemUptime("0:00:00"), m_batteryStatus("Unknown") {

    qRegisterMetaType<QMap<QString, float>>("QMap<QString, float>");
    qRegisterMetaType<std::function<void()>>("std::function<void()>");
    m_cpuUsageMap["cpu"] = 100;
    m_cpuUsageMap["cpu0"] = 200;
    m_cpuUsageMap["cpu1"] = 300;
    m_metrics["cpu"] = {3000, 0, [this]() { fetchCpuUsage(); }};
    m_metrics["memory"] = {3000, 0, [this]() { fetchMemoryUsage(); }};
    m_metrics["temperature"] = {3000, 0, [this]() { fetchTemperature(); }};
    m_metrics["threadPool"] = {3000, 0, [this]() { fetchThreadPoolUsage(); }};
    m_metrics["currentTime"] = {1000, 0, [this]() { fetchCurrentTime(); }};
    m_metrics["disk"] = {3000, 0, [this]() { fetchDiskUsage(); }};
    m_metrics["network"] = {3000, 0, [this]() { fetchNetworkUsage(); }};
    m_metrics["gpu"] = {3000, 0, [this]() { fetchGpuUsage(); }};
    m_metrics["uptime"] = {3000, 0, [this]() { fetchSystemUptime(); }};
    m_metrics["battery"] = {3000, 0, [this]() { fetchBatteryStatus(); }};
    //m_metrics["NetServe"] = {10000, 0, [=]() { NetworkManager::instance()->connectToServer(); }};
    // Initialize the worker thread and connect signals
    m_worker.moveToThread(&m_workerThread);
    connect(this, &SystemMonitor::processTask, &m_worker, &Worker::processTask);
    m_workerThread.start();

    m_cameraWorker.moveToThread(&m_cameraWorkerThread);
    connect(this, &SystemMonitor::processCameraTask, &m_cameraWorker, &CameraWorker::monitorParameters);
    m_cameraWorkerThread.start();


    connect(&m_timer, &QTimer::timeout, this, &SystemMonitor::scheduleMetricsUpdate);
    m_timer.start(1000); // 每秒检查一次

    connect(this, &SystemMonitor::scheduleNextTask, this, &SystemMonitor::processNextTask);

    LogInfo << "SystemMonitor initialized.";
}

SystemMonitor::~SystemMonitor() {
    m_workerThread.quit();
    m_workerThread.wait();

    m_cameraWorkerThread.quit();
    m_cameraWorkerThread.wait();
}

void SystemMonitor::initializeTimer() {
    connect(&m_timer, &QTimer::timeout, this, &SystemMonitor::scheduleMetricsUpdate);
}

void SystemMonitor::setRefreshInterval(const QString &metric, int interval) {
    if (m_metrics.contains(metric)) {
        m_metrics[metric].interval = interval;
    }
}

void SystemMonitor::scheduleMetricsUpdate() {
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
    for (auto it = m_metrics.begin(); it != m_metrics.end(); ++it) {
        if (currentTime - it.value().lastUpdateTime >= it.value().interval) {
            m_taskQueue.enqueue(it.value().fetchFunction);
            it.value().lastUpdateTime = currentTime;
        }
    }
    emit scheduleNextTask();
    emit processCameraTask();
}

void SystemMonitor::processNextTask() {
    if (!m_taskQueue.isEmpty()) {
        auto task = m_taskQueue.dequeue();
        emit processTask(task);
        emit scheduleNextTask();
    }
}

void SystemMonitor::fetchCpuUsage() {
    fetchTotalCpuUsage();
    fetchPerCoreCpuUsage();
    emit cpuUsageChanged();
}

void SystemMonitor::fetchTotalCpuUsage() {
    QProcess process;
    process.start("top -bn1");
    process.waitForFinished();
    QString output = process.readAllStandardOutput();

    QStringList lines = output.split("\n");
    for (const QString& line : lines) {
        if (line.contains("Cpu(s):")) {
            QStringList values = line.split(QRegExp("\\s+"), QString::SkipEmptyParts);
            for (int i = 0; i < values.size(); ++i) {
                if (values[i].contains("id,")) {
                    // 获取空闲率
                    float idle = values[i - 1].toFloat();
                    // 计算使用率
                    float totalCpuUsage = 100.0 - idle;
                    if (totalCpuUsage != m_cpuUsage) {
                        m_cpuUsage = totalCpuUsage;
                    }
                    return; // 找到后立即返回
                }
            }
        }
    }
    qDebug() << "Failed to find total CPU usage.";
}
void SystemMonitor::fetchPerCoreCpuUsage() {
    //LogDebug << "Opening /proc/stat";
    std::ifstream file("/proc/stat");
    if (!file.is_open()) {
        LogError << "Failed to open /proc/stat";
        return;
    }

    QMap<QString, CpuData> currentCpuData;

    std::string line;
    int lineCount = 0; // 计数器，记录读取的行数

    while (std::getline(file, line)) {
        //LogDebug << "Read line: " << QString::fromStdString(line);
        lineCount++;

        if (line.compare(0, 3, "cpu") == 0 && line != "cpu") {
            std::istringstream ss(line);
            std::string cpuName;
            quint64 user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice;
            ss >> cpuName >> user >> nice >> system >> idle >> iowait >> irq >> softirq >> steal >> guest >> guest_nice;

            if (ss.fail() || ss.bad()) continue;

            CpuData data;
            data.name = QString::fromStdString(cpuName);
            data.user = user;
            data.nice = nice;
            data.system = system;
            data.idle = idle;
            data.iowait = iowait;
            data.irq = irq;
            data.softirq = softirq;
            data.steal = steal;
            data.guest = guest;
            data.guest_nice = guest_nice;

            currentCpuData[data.name] = data;
            //LogDebug << "Data name: " << data.name;
            if (m_previousCpuData.contains(data.name)) {
                const CpuData& previousData = m_previousCpuData[data.name];
                quint64 totalDiff = data.totalTime() - previousData.totalTime();
                quint64 activeDiff = data.activeTime() - previousData.activeTime();
                float usage = 100.0 * activeDiff / totalDiff;
                m_cpuUsageMap[data.name] = usage;
                //LogDebug << "CPU " << data.name << " usage: " << usage;
            }
        }
    }

    file.close();
    m_previousCpuData = currentCpuData;
    //LogDebug << "Completed fetching per core CPU usage. Total lines read: " << lineCount;
}

void SystemMonitor::fetchMemoryUsage() {
    QProcess process;
    process.start("free");
    process.waitForFinished();
    QString output = process.readAllStandardOutput();

    // 找到包含 "Mem:" 的行
    QStringList lines = output.split("\n");
    QString memLine;
    for (const QString& line : lines) {
        if (line.startsWith("Mem:")) {
            memLine = line;
            break;
        }
    }

    if (!memLine.isEmpty()) {
        QStringList values = memLine.split(QRegExp("\\s+"), QString::SkipEmptyParts);
        if (values.size() > 2) {
            float total = values[1].toFloat();
            float used = values[2].toFloat();
            m_memoryUsage = 100.0 * used / total;
            //LogDebug << "Memory Usage:" << m_memoryUsage << "%";
            emit memoryUsageChanged();
        }
    } else {
        LogError << "Failed to fetch memory usage: 'Mem:' line not found.";
    }
}

void SystemMonitor::fetchTemperature() {
    QProcess process;
    process.start("sensors");
    process.waitForFinished();
    QString output = process.readAllStandardOutput();

    QStringList lines = output.split("\n");
    float maxTemperature = -1.0;

    for (const QString& line : lines) {
        if (line.contains("temp1:")) {
            QStringList values = line.split(QRegExp("\\s+"), QString::SkipEmptyParts);
            if (values.size() > 1) {
                float temperature = values[1].remove('+').remove('°C').toFloat();
                if (temperature > maxTemperature) {
                    maxTemperature = temperature;
                }
            }
        }
    }

    if (maxTemperature >= 0) {
        m_temperature = maxTemperature;
        //LogDebug << "CPU Temperature:" << m_temperature << "°C";
        emit temperatureChanged();
    } else {
        LogError << "Failed to find any temperature readings.";
    }
}

void SystemMonitor::fetchThreadPoolUsage() {
    QThreadPool *threadPool = QThreadPool::globalInstance();
    int activeThreads = threadPool->activeThreadCount();
    int maxThreads = threadPool->maxThreadCount();
    m_threadPoolUsage = QString("%1/%2").arg(activeThreads).arg(maxThreads);

    // LogDebug << "Thread Pool Usage:" << m_threadPoolUsage;  // 可选：用于调试
    emit threadPoolUsageChanged();
}

void SystemMonitor::fetchCurrentTime() {
    m_currentTime = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");
    //LogDebug << "Current Time:" << m_currentTime;
    emit currentTimeChanged();
}

void SystemMonitor::fetchDiskUsage() {
    QProcess process;
    process.start("df /");
    process.waitForFinished();
    QString output = process.readAllStandardOutput();

    QStringList lines = output.split("\n");
    if (lines.size() > 1) {
        QStringList values = lines[1].split(QRegExp("\\s+"), QString::SkipEmptyParts);
        ////LogDebug << "Parsed values:" << values;
        if (values.size() > 4) {
            QString diskUsageStr = values[4];
            ////LogDebug << "Disk usage string:" << diskUsageStr;
            m_diskUsage = diskUsageStr.remove('%').toFloat();
            //LogDebug << "Disk Usage:" << m_diskUsage << "%";
            emit diskUsageChanged();
        } else {
            LogError << "Failed to parse disk usage values. Line: " << lines[1];
        }
    } else {
        LogError << "Failed to read disk usage. Output: " << output;
    }
}

void SystemMonitor::fetchNetworkUsage() {
    m_networkUpload = qrand() % 100;
    m_networkDownload = qrand() % 100;
    //LogDebug << "Network Upload:" << m_networkUpload << " KB/s";
    //LogDebug << "Network Download:" << m_networkDownload << " KB/s";
    emit networkUploadChanged();
    emit networkDownloadChanged();
}

void SystemMonitor::fetchGpuUsage() {
    m_gpuUsage = qrand() % 100;
    m_gpuTemperature = 40.0 + (qrand() % 10);
    //LogDebug << "GPU Usage:" << m_gpuUsage << "%";
    //LogDebug << "GPU Temperature:" << m_gpuTemperature << "°C";
    emit gpuUsageChanged();
    emit gpuTemperatureChanged();
}

void SystemMonitor::fetchSystemUptime() {
    QProcess process;
    process.start("uptime -p");
    process.waitForFinished();
    m_systemUptime = process.readAllStandardOutput().trimmed();
    //LogDebug << "System Uptime:" << m_systemUptime;
    emit systemUptimeChanged();
}

void SystemMonitor::fetchBatteryStatus() {
    m_batteryStatus = "Charging";
    //LogDebug << "Battery Status:" << m_batteryStatus;
    emit batteryStatusChanged();
}
